/****************************************************
 * File: gtktrack.h
 *
 * Author: Fred Engler
 *
 * Description: Contains all the data structures used
 * for the GtkTrack widget, as well as various other
 * structures used for the GTK contig display.
 * If you need to define a new global variable for the 
 * contig display, you probably want to put it here.
 ****************************************************/

#ifndef INC_GTK_TRACK_H
#define INC_GTK_TRACK_H

#include <gtk/gtk.h>
#include <search.h>
#include <ctype.h>
#include "clam.h"

#define GTK_TRACK(obj)          GTK_CHECK_CAST (obj, gtk_track_get_type (), GtkTrack)
#define GTK_TRACK_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_track_get_type (), GtkTrackClass)
#define GTK_IS_TRACK(obj)       GTK_CHECK_TYPE (obj, gtk_track_get_type ())

/* Masks used to set and check status of 'high' field in entity structs*/
#define HIGH_ACTIVE_MASK 1           /*Entity is the main highlighted entity*/
#define HIGH_PASSIVE1_MASK 2         /*Entity is related to main highlight*/
#define HIGH_PASSIVE2_MASK 4         /*Entity buried in this entity is related to main highlight*/
#define SELECTED_MASK 8              /*Clone is selected*/
#define HIGH_MATCH1_MASK 16          /*Entity matches search string*/
#define HIGH_MATCH2_MASK 32          /*Entity buried in this entity matches search string*/
#define HIGH_OTHER_MASK 64           /*Entity is highlighted some other color*/

#define DEFAULT_TRACK_WIDTH  700     /*Default track width*/
#define DEFAULT_TRACK_HEIGHT 200     /*Default track height; generally overridden*/
#define RESIZE_AREA_HEIGHT 6         /*Width of the clickable area used for resizing track height*/
#define SCROLLBAR_WIDTH 22           /*Width of the track's scrollbar*/
#define SCROLLED_WINDOW_BORDER 2     /*Horizontal border height of the track's scrolled window*/

#define MAXIMUM_DISPLAY_WIDTH 32767  /*Maximum width of a pixmap -- GTK limit*/

/* Evaluates to TRUE if any part of the clone 
 * is located within the bounds of the current page*/
#define CLONE_ON_PAGE(l,r) (((l>=page_end_left && l<=page_end_right)|| \
                             (r>=page_end_left && r<=page_end_right)) ? TRUE : FALSE)

/* Evaluates to TRUE if the midpt of the marker 
 * is located within the bounds of the current page*/
#define MARKER_ON_PAGE(p) ((p>=page_end_left && p<=page_end_right) ? TRUE : FALSE)

/* GtkTrack widget definitions*/
typedef struct _GtkTrack       GtkTrack;
typedef struct _GtkTrackClass  GtkTrackClass;

/*GtkTrack-specific enumerations for determining what entities are shown in a track,
 *and how they are colored.*/
enum entities {NONE, MARKERS, CLONES, REMARKS, ANCHORS, SEQUENCE};
enum markerTypes {ANY_MARK, BAC_MARK, CDNA_MARK, CLONE_MARK, COSMID_MARK, EBAC_MARK, EMRK_MARK, 
                  END_MARK, FOSMID_MARK, LOCUS_MARK, OVERGO_MARK, PAC_MARK, PCR_MARK, PROBE_MARK, 
                  REPEAT_MARK, RFLP_MARK, SNP_MARK, SSR_MARK, STS_MARK, TC_MARK, YAC_MARK,
                  FRAME_MARK, PLACE_MARK};
enum cloneTypes {ANY_CLONE, BAC_CLONE, CLONE_CLONE, COSMID_CLONE, FOSMID_CLONE, PAC_CLONE, 
                 SEQ_CLONE, YAC_CLONE, PARENT_CLONE, PSPARENT_CLONE, EXACT_CLONE, APPROX_CLONE,
                 PSEUDO_CLONE};
enum remarkTypes {ANY_REMARK, CLONE_REMARK, CLONE_FPREMARK, MARKER_REMARK};
enum anchorTypes {ANY_ANCHOR, FRAME_ANCHOR, PLACE_ANCHOR};
enum seqTypes {ANY_SEQ, DRAFT_SEQ, CLONE_SEQ, REVERSED_SEQ};
enum chromTypes {ANY_CHROM, GOOD_CHROM, BAD_CHROM};
enum attachTypes {ANY_ATTACH, ONECLONE_ATTACH, MULTCTG_ATTACH};
enum statusTypes {ANY_STATUS, NONE_STATUS, TILE_STATUS, SENT_STATUS, READY_STATUS, SHOTGUN_STATUS,
                  FINISHED_STATUS, SD_STATUS, CANCELLED_STATUS};
enum colors {HIDE_COLOR, BLACK_COLOR, RED_COLOR, ORANGE_COLOR, YELLOW_COLOR, GREEN_COLOR, 
             BLUE_COLOR, VIOLET_COLOR, GRAY_COLOR, CUSTOM_COLOR};
enum rowPolicies {AUTO_POLICY, FIT_POLICY, LIMIT_POLICY};

/*Differnt ways an entity can be highlighted*/
enum highlightTypes {CLEAR1, CLEAR2, 
                     CLONE_ACTIVE, CLONE_PASSIVE1, CLONE_PASSIVE2, CLONE_SELECTED,
                     MARKER_ACTIVE, MARKER_PASSIVE, 
                     REMARK_ACTIVE, REMARK_PASSIVE, 
                     MATCH1, MATCH2,
                     ACEDB_COLOR,
                     SEQUENCE_ACTIVE, SEQUENCE_CTG_ACTIVE};

/*The end points of the area currently viewable in the ctgdisplay*/
int page_end_left;
int page_end_right;
int page_size;

int checked_width;   /*Used to supress revert to previously set page size on redraw*/
int handled_bpress;  /*TRUE if the track handled the button press*/

/* Structs for reading in ctg layout from fpp file*/
struct layout_filter_info{
  char name[CLONE_SZ+1];          /*Filter on entity name*/
  char remark[COMMENT_SZ+1];      /*Filter on remarks attached to entity*/
  int type;                       /*Filter on entity type*/
  int status;                     /*Filter on sequence status*/
  int chrom;                      /*Filter on chromosome assignment*/
  int attachment;                 /*Filter on marker attachment to clones*/
  enum colors color_choice;       /*Color of entities meeting filter criteria*/
  GdkColor color;                 /*RGB values for color_choice (needed for Custom)*/
  struct layout_filter_info *next;
};

struct layout_track_info{
  enum entities entity;           /*Marker, Clone, Remark, Anchor...*/
  enum rowPolicies row_policy;    /*How the entities are displayed*/
  int numrows;                    /*Number of rows to display entities on*/
  int height;                     /*Height of the track*/
  int show_anchor_bins;           /*For anchor tracks; whether or not all anchor bins are shown*/
  int show_anchor_pos;            /*For anchor tracks; whether or not anchor positions are shown*/
  int show_anchor_lines;          /*For anchor tracks; whether or not vertical lines are shown*/
  struct layout_filter_info *filters; /*Filters for this track*/
  struct layout_track_info *next;
};

struct layout_ctg_info{
  BOOL defined;       /*TRUE iff we have a layout defined for this ctg; else use default*/
  float zoom;         /*Value of the zoom adjustment*/
  int bury;           /*Do we display buried clones?*/
  struct layout_track_info *tracks;
};

/* Structs for information that is shown in track*/
struct t_remark{
   char message[COMMENT_SZ+1]; /*The actual remark string*/
   int pos;                    /*The midpoint position in CB units on the map; same as the middle
                                *of the clone/marker it's attached to*/
   enum remarkTypes type;      /*The remark type*/
   int mattype;          /*PARENT, PSPARENT, EXACT, APPROX, PSEUDO bitfields of 
                          *corresponding clone; always 0 for markers. */
   int index;            /*Index of clone that remark is attached to, or
                          *negative of index that marker is attached to (to keep unique id)*/
   int high;             /*Binary bit fields for active, passive1, passive2, selected, etc*/
   GdkColor color;       /*Color of the remark; set according to matched filter*/
   GdkRectangle hotspot; /*Area surrounding text that is clickable*/
   GdkPixmap *pixmap;    /*Pixmap of hotspot for restoring after highlight cleared*/
};

struct t_marker{
   char marker[MARKER_SZ+1];  /*The marker name*/
   int index;             /*Index into markerdata array*/
   int pos;               /*Midpoint in CB units on the map*/
   int high;              /*Binary bit fields for active, passive1, passive2, selected, etc*/
   GdkColor color;        /*Color of the marker; set according to matched filter*/
   GdkRectangle hotspot;  /*Area surrounding text that is clickable*/
   GdkPixmap *pixmap;     /*Pixmap of hotspot for restoring after highlight cleared*/
};

struct t_anchor{
   char marker[MARKER_SZ+1];  /*The anchor name*/
   int index;                 /*Index into markerdata array*/
   int pos;                   /*Midpoint in CB units on the map*/
   int high;                  /*Binary bit fields for active, passive1, passive2, selected, etc*/
   char anchor_bin[ANCHOR_BIN_SZ+1];  /*Chromosome/Linkage_group, etc. assignment*/
   GdkColor color;            /*Color of the anchor; set according to matched filter*/
   GdkRectangle hotspot;      /*Area surrounding text that is clickable*/
};

struct t_clone{
   char clone[CLONE_SZ+1];  /*The clone name*/
   int index;               /*Index into acedata array*/
   int left, right;         /*Left and right endpoints of clone*/
   int mattype;             /*PARENT, PSPARENT, EXACT, APPROX, PSEUDO bitfields*/
   int high;                /*Binary bit fields for active, passive1, passive2, selected, etc*/
   GdkColor color;          /*Color of the clone; set according to matched filter*/
   GdkRectangle hotspot;    /*Area surrounding text that is clickable*/
   GdkPixmap *pixmap;       /*Pixmap of hotspot for restoring after highlight cleared*/
};

struct t_seq{
   FPC_SEQ* seq;              /*The sequence data object*/
   struct seqctgpos* ctgpos;    /* the particular alignment */ 
   int cycle;
   int nclicks;             /* how many times user clicked the highlighted seq */
   struct fpc_seq_list* highctg;
   int left, right;         /*Left and right endpoints on the contig*/
   int seq_left, seq_right;         /*Left and right endpoints on the sequence*/
   float corr;
   int high;                /*Binary bit fields for active, passive1, passive2, selected, etc*/
   GdkColor color;          /*Color of the seq; set according to matched filter*/
   GdkRectangle hotspot;    /*Area surrounding text that is clickable*/
   GdkRectangle hotspot_prev;    /*previous contig*/
   GdkRectangle hotspot_next;    /*next contig*/
   int ctg_prev;
   int ctg_next;
   int row;
   GdkPixmap *pixmap;       /*Pixmap of hotspot for restoring after highlight cleared*/
};

struct filters{
   char name[CLONE_SZ+1];     /*Filter on entity name*/
   int type;                  /*Filter on entity type*/
   int status;                /*Filter on clone status*/
   int chrom;                 /*Whether or not frameworks are on correct chromosome*/
   int attachment;            /*For markers -- for One Clone or MultCtg*/
   char remark[COMMENT_SZ+1]; /*Filter on remark attached to entity*/
   enum colors color_choice;  /*The color selection for entities matching filter criteria*/
   GdkColor color;            /*RGB values for selected color*/
   int ignore;                /* True if filter to be ignored; currently used for the
                               * [Click here to add filter] clist item*/
   struct filters *next;
};

union entityList{
   struct t_remark *remarkList;   /*used if entity==REMARKS*/
   struct t_marker *markerList;   /*used if entity==MARKERS*/
   struct t_anchor *anchorList;   /*used if entity==ANCHORS*/
   struct t_clone *cloneList;     /*used if entity==CLONES*/
   struct t_seq *seqList;         /*used if entity==SEQUENCE*/
};



/* The main structure for the GtkTrack widget.*/
struct _GtkTrack
{
  GtkVBox vbox;               /*Inherit from GtkVBox*/
  
  enum entities entity;       /*Clone, Marker, Remark, Anchor...*/
  struct filters *filterList; /*The list of filters in use for this track*/
  int numrows;                /*Number of rows to show entities on*/
  int rowspacing;             /*Spacing in pixels between rows*/
  int default_height;         /*Default height when adding as new track*/
  int numdata;                /*Number of displayed entities in track*/
  int track_pos;              /*Position of track with respect to other tracks*/
  int track_pos_new;          /*New position if changed via Edit Track Properties*/
  union entityList data;      /*The structure holding information for each entity 
                               *displayed in track*/
  int highdata;               /*Index of currently highlighted entity*/
  int focusdata;              /*Index of entity over which mouse was positioned 
                               *when right-click.  Used to show clone-specific menu*/
  int limit_rows;             /*Don't go over this many rows.  Used for 'Limit' row policy*/
  enum rowPolicies row_policy;/*How we want to show the data*/
  int show_anchor_bins;       /*Used for anchor tracks to toggle displaying of anchor bins*/
  int show_anchor_pos;        /*Used for anchor tracks to toggle displaying of anchor pos*/
  int show_anchor_lines;      /*Used for anchor tracks to toggle drawing vertical anchor lines*/

  /* Backup in case Cancel is clicked from Edit Track Properties*/
  struct filters *tmp_filterList;
  enum rowPolicies tmp_row_policy;
  int tmp_numrows;
 
  struct filters *current_filter;  /*Pointer to the currently selected filter*/
  int selected_filter;             /*Index in clist of the currently selected filter*/

  /*Graphics stuff*/
  GtkWidget *scrolled_window;  /*The window into which the drawing area is placed.
                                *It has an independent hadj, but uses main_hadj to
                                *scroll horizontally.*/
  GtkWidget *drawing_area;     /*The area onto which the pixmap is drawn*/
  GdkPixmap *pixmap;           /*The main backing pixmap*/
  GdkColormap *colormap;       /*Main colormap for track*/
  GdkPixmap *shade_pixmap;     /*Used in anchor track for shading anchors not currently displayed*/
  GdkBitmap *mask;             /*For anchor track; mask of what to redraw*/

  /* Edit Track Properties (ETP) window stuff*/
  GtkWidget *edit_track_window;/*The ETP window*/
  GtkWidget *filter_clist;     /*The clist for the track filters*/
  GtkWidget *name_entry;       /*The name entry in ETP*/
  GtkWidget *remark_entry;     /*The remark entry in ETP*/
  GtkWidget *type_menu;        /*The type menu in ETP*/
  GtkWidget *type_optionmenu;  /*The optionmenu containing type_menu*/
  GtkWidget *chrom_menu;       /*The chromosome assignment menu in ETP*/
  GtkWidget *chrom_optionmenu; /*The optionmenu containing chrom_menu*/
  GtkWidget *attach_menu;      /*The marker attachment menu in ETP*/
  GtkWidget *attach_optionmenu;/*The optionmenu containing attach_menu*/
  GtkWidget *status_menu;      /*The clone sequence status menu in ETP*/
  GtkWidget *status_optionmenu;/*The optionmenu containing status_menu*/
  GtkWidget *colorseldlg;      /*The dialog window for selecting a custom color*/
  GtkWidget *color_menu;       /*The color menu in ETP*/
  GtkWidget *color_optionmenu; /*The optionmenu containing color_menu*/
  GtkWidget *custom_item;      /*The item in color_menu for custom color.  Needed here so we
                                *can change the color of the item according to color selected*/
  GtkWidget *row_spin_button;  /*The spinn button giving number of rows for 'Limit' row policy*/
  GtkWidget *generic_popup_menu;/*The menu shown when right-clicking in a blank area of track*/
  GtkWidget *clone_popup_menu; /*The menu shown when right-clicking on a clone
                                    (also used for sequences) */

  GtkObject *hadj;             /*Same as main_hadj*/

  int contig_pixel_width;      /*The width of the drawing area/pixmap in pixels*/
  int contig_pixel_height;     /*The height of the drawing area/pixmap in pixels*/

  /* Track resize stuff*/
  GtkWidget *resize_area;      /*A drawing area for clicking and dragging to alter track height*/
  gint cursor_set;             /*True if we have the cursor for the resize area*/
  gint line_pos;               /*Position of the line in pixels that gets drawn during dragging*/
  gint view_height;            /*The new height of the track if a valid resize was performed;
                                *initially -1*/
  gint in_drag;                /*True if we are currently resizing*/

  GdkGC *gc;                   /*The main graphics context for the track*/
  GdkGC *xor_gc;               /*The graphics context for the line that gets drawn during resize*/
  GdkGC *high_gc;              /*The graphics context for highlighted entities*/
  GdkGC *shade_gc;             /*The graphics context for drawing the shade in anchor tracks*/
  GdkGC *dotln_gc;             /*The graphics context for drawing the dotted line in disconnected
                                *contigs*/
};

/*Boilerplate widget initialization stuff*/
struct _GtkTrackClass
{
  GtkVBoxClass parent_class;
};

/* Function prototypes*/
GtkType gtk_track_get_type (void);
GtkWidget* gtk_track_new (void);
void gtk_track_set_hadjustment(GtkTrack *track, GtkAdjustment *adj);
void gtk_track_set_entity(GtkTrack *track, enum entities e, 
                          int height, enum rowPolicies row_policy, int numrows, 
                          int show_anchor_bins, int show_anchor_pos, int show_anchor_lines);
void gtk_track_add_filter(GtkTrack *t, char *name, char *remark, 
                          int type, int status, int chrom, int attach, enum colors color_choice,
                          GdkColor *clr);
int configure_event(GtkWidget *widget, GdkEventConfigure *event, GtkTrack *track);
void compute_track_size(GtkTrack *t);
void draw_anchor_shade(GtkTrack *t);
int compare_clones_name(struct t_clone *p1, struct t_clone *p2);
int compare_markers_name(struct t_marker *p1, struct t_marker *p2);
int compare_anchors_name(struct t_anchor *p1, struct t_anchor *p2);
int compare_remarks_name(struct t_remark *p1, struct t_remark *p2);
int compare_clones_left(struct t_clone *p1, struct t_clone *p2);
int compare_markers_pos(struct t_marker *p1, struct t_marker *p2);
int compare_anchors_pos(struct t_anchor *p1, struct t_anchor *p2);
int compare_remarks_pos(struct t_remark *p1, struct t_remark *p2);
int compare_strings(char *sbjct, char *pattern);
void gtk_track_clear_data(GtkTrack *t);
void zero_left_end(int ctg);
void gtk_track_fill_data(GtkTrack *t);


extern int HOTSPOT_HEIGHT;             /*Height of the clickable rectangle surrounding an entity*/
extern int text_height;

#endif /* __GTK_TRACK_H__ */
